﻿using System;
using System.Text;
using System.Ext.Xml;
using System.Xml;

namespace mfXmlSerializer
{
    /// <summary>
    /// represents the required 4 (de-)serialization
    /// a map serialize (her-)self in a parent-element
    /// </summary>
    public class mfSerializationMap : IDisposable
    {

        #region CTOR

        /// <summary>
        /// ctor 4 map, requires the target type 4 lookup
        /// </summary>
        /// <param name="name">name of the map</param>
        /// <param name="targetType">target type 4 map</param>
        public mfSerializationMap(string name, Type targetType) {

            SerializationElements = new mfMapElementCollection();

            TargetType = targetType;
            Name = name;
        }

        #endregion

        #region Properties
        /// <summary>
        /// child map elements
        /// </summary>
        public mfMapElementCollection SerializationElements { get; private set; }
        /// <summary>
        /// target type 4 lookup
        /// </summary>
        public Type TargetType { get; set; }
        /// <summary>
        /// name of this map (used 4 element serialization)
        /// </summary>
        public string Name{ get; set; }
        #endregion

        #region Methods
        /// <summary>
        /// starts serialization on this map
        /// </summary>
        /// <param name="xmlWriter">xml writer object 2 write on</param>
        /// <param name="target">target object 2 read</param>
        /// <param name="elementSerializedAction">optional, action triggered after this element is serialized</param>
        public void SerializeMap(XmlWriter xmlWriter, Object target, mfDelElementSerialized elementSerializedAction = null) 
        {
            //write root element
            xmlWriter.WriteStartElement(Name);

            //invoke element-serialzied-event after start-element!!!
            mfXmlTypedSerializer.OnElementSerialzed(elementSerializedAction, xmlWriter, this.Name);

            foreach (mfMapBaseElement element in SerializationElements)
            {
                element.Serialize(xmlWriter, target, elementSerializedAction);
            }

            //end root element
            xmlWriter.WriteEndElement();
        }

        /// <summary>
        /// starts deserialization on this map
        /// </summary>
        /// <param name="xmlReader">xml reader object 2 read on</param>
        /// <param name="target">target object 2 write</param>
        public void DeserializeMap(XmlReader xmlReader, Object target) 
        {
            xmlReader.AssertIfMapIsInvalid(this);

            xmlReader.Read();

            foreach (mfMapBaseElement element in SerializationElements)
            {
                element.Deserialize(xmlReader, target);
            }
        }

        #endregion

        #region IDisposable
        public void Dispose()
        {
            this.Name = null;
            this.TargetType = null;

            foreach (mfMapBaseElement child in this.SerializationElements)
                child.Dispose();

            if (this.SerializationElements.Count > 0)
                SerializationElements.Clear();
        } 
        #endregion
    }
}
